/*
 * Powered By xTOOLs
 * Dev by DuRisk@pactera.com
 * Copyright © 2009 - 2017 pactera.com. All rights reserved.
 *
 * Generated at 2017年11月17日 14:25:59
 *
 */

package com.pactera.jep.service.sys.web.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.pactera.jep.autoconfigure.web.controller.BaseRestController;
import com.pactera.jep.commons.CollectionUtils;
import com.pactera.jep.core.code.PermitType;
import com.pactera.jep.core.code.Status;
import com.pactera.jep.core.context.Context;
import com.pactera.jep.core.exception.ServiceException;
import com.pactera.jep.orm.Filter;
import com.pactera.jep.orm.Order;
import com.pactera.jep.orm.Page;
import com.pactera.jep.service.sys.security.spring.bean.UserEntity;
import com.pactera.jep.service.sys.util.UserEntityUtil;
import com.pactera.jep.sys.code.DashWidgetType;
import com.pactera.jep.sys.dash.provider.DataProvider;
import com.pactera.jep.sys.dash.provider.DataProviderFactory;
import com.pactera.jep.sys.dash.provider.service.IDataProviderService;
import com.pactera.jep.sys.dash.provider.spring.SpringDataProviderFactoryBean;
import com.pactera.jep.sys.dash.widget.WidgetFactory;
import com.pactera.jep.sys.dash.widget.configable.chart.ChartRenderer;
import com.pactera.jep.sys.dash.widget.configable.chart.ChartRendererFactory;
import com.pactera.jep.sys.model.DashWidget;
import com.pactera.jep.sys.model.DashWidgetConfig;
import com.pactera.jep.sys.model.DashWidgetProvider;
import com.pactera.jep.sys.service.DashWidgetConfigService;
import com.pactera.jep.sys.service.DashWidgetDakService;
import com.pactera.jep.sys.service.DashWidgetProviderService;
import com.pactera.jep.sys.service.DashWidgetService;
import com.pactera.jep.web.code.WebCode;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(value = "组件管理")
@RestController
@RequestMapping("/dashWidget")
public class DashWidgetRestController extends BaseRestController<DashWidget> {
	private static Logger logger = LoggerFactory.getLogger(DashWidgetRestController.class);

	@Autowired
	private DashWidgetService dashWidgetService;

	@Autowired
	private DashWidgetProviderService dashWidgetProviderService;

	@Autowired
	private DashWidgetConfigService dashWidgetConfigService;

	@Autowired
	private DashWidgetDakService dashWidgetDakService;

	@Autowired
	private SpringDataProviderFactoryBean factoryBean;

	@Autowired
	private IDataProviderService dataProviderService;

	@Override
	public Map<String, Object> query(String token, Page<DashWidget> page, Model model, HttpServletRequest request) {
		return super.query(token, page, model, request);
	}

	/**
	 * 为列表页面做数据准备
	 */
	@ApiOperation("为列表页面做数据准备")
	@Override
	protected void prepareQuery(String token, Page<DashWidget> page, List<Filter> filters, List<Order> orders,
			HttpServletRequest request) {

		dashWidgetService.query(page, filters, orders);
	}

	/**
	 * 保存
	 * 
	 * @param dashWidget
	 * @return
	 */
	@ApiOperation("保存一条数据")
	@PostMapping(value = "/save")
	public Map<String, Object> save(@RequestBody DashWidget dashWidget) {

		Map<String, Object> tips = new HashMap<String, Object>();

		Boolean isExist = dashWidgetService.exists(dashWidget.getCode());
		try {
			if (isExist) {

				dashWidgetService.updateSelective(dashWidget);
			} else {
				dashWidgetService.saveWidget(dashWidget);
			}

			tips.put(WebCode.SUCCESS, true);
			tips.put(WebCode.MSG, WebCode.SUCCESS_SAVE);
		} catch (ServiceException e) {
			logger.info(e.getMessage());
			tips.put(WebCode.SUCCESS, false);
			tips.put(WebCode.MSG, WebCode.FAILURE_SAVE);
		}
		return tips;
	}

	/**
	 * 删除组件及其配置
	 * 
	 * @param code
	 * @return
	 */
	@ApiOperation("删除一条数据")
	@PostMapping(value = "/remove/{code}")
	public Map<String, Object> remove(@PathVariable String code) {

		Map<String, Object> tips = new HashMap<String, Object>();

		try {
			dashWidgetService.deleteWidget(code);
			tips.put(WebCode.SUCCESS, true);
			tips.put(WebCode.MSG, WebCode.SUCCESS_DELETE);
		} catch (ServiceException e) {
			logger.info(e.getMessage());
			tips.put(WebCode.SUCCESS, false);
			tips.put(WebCode.MSG, WebCode.FAILURE_DELETE);
		}

		return tips;
	}

	/**
	 * 验证提交的code是否已经存在数据库中
	 * 
	 * @param code
	 * @return
	 */
	@RequestMapping(value = "/check", produces = "application/json;charset=UTF-8")
	public Map<String, Object> check(String code) {

		Map<String, Object> tips = new HashMap<String, Object>();

		boolean exist = dashWidgetService.exists(code);
		tips.put("valid", !exist);

		return tips;
	}

	/**
	 * 判断能否启用组件
	 * 
	 * @param code
	 * @return
	 */
	@ApiOperation("判断能否启用组件")
	@PostMapping(value = "/canEnable/{code}")
	public Map<String, Object> canEnable(@PathVariable String code) {
		Map<String, Object> tips = new HashMap<String, Object>();

		DashWidgetConfig dashWidgetConfig = dashWidgetConfigService.get(code);
		String widgetConfig = dashWidgetConfig.getConfig();

		/* 当配置数据存在的话，进行进一步初始化，若无异常，则能启用 */
		if (!StringUtils.isEmpty(widgetConfig)) {
			try {
				/* 获取当前用户在该组件上的权限 */
				// UserProfile user = UserProfileUtils.getUserProfile();
				UserEntity userEntity = UserEntityUtil.getCurrentUser();
				// PermitType permitType =
				// dashWidgetDakService.queryMaxDashWidgetDak(user.getStaffCode(), code);
				PermitType permitType = dashWidgetDakService.queryMaxDashWidgetDak(userEntity.getUserId(), code);

				WidgetFactory.createWidget(code, permitType);
				tips.put(WebCode.SUCCESS, true);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error(e.getMessage(), e);
				tips.put(WebCode.SUCCESS, false);
			}
		} else {
			tips.put(WebCode.SUCCESS, false);
		}
		return tips;
	}

	/**
	 * 启用
	 * 
	 * @param code
	 * @return
	 */
	@ApiOperation("启用组件")
	@PostMapping(value = "/enable/{code}")
	public Map<String, Object> enable(@PathVariable String code) {

		Map<String, Object> tips = new HashMap<String, Object>();

		try {
			DashWidget dashWidget = dashWidgetService.get(code);
			dashWidget.setStatus(Status.ENABLED.getValue());
			dashWidgetService.update(dashWidget);

			tips.put(WebCode.SUCCESS, true);
			tips.put(WebCode.MSG, WebCode.SUCCESS_ENABLE);
		} catch (ServiceException e) {
			logger.info(e.getMessage());
			tips.put(WebCode.SUCCESS, false);
			tips.put(WebCode.MSG, WebCode.FAILURE_ENABLE);
		}

		return tips;
	}

	/**
	 * 停用
	 * 
	 * @param code
	 * @return
	 */
	@ApiOperation("停用组件")
	@PostMapping(value = "/disable/{code}")
	public Map<String, Object> disable(@PathVariable String code) {

		Map<String, Object> tips = new HashMap<String, Object>();

		try {
			DashWidget dashWidget = dashWidgetService.get(code);
			dashWidget.setStatus(Status.DISABLED.getValue());
			dashWidgetService.update(dashWidget);

			tips.put(WebCode.SUCCESS, true);
			tips.put(WebCode.MSG, WebCode.SUCCESS_DISABLE);
		} catch (ServiceException e) {
			logger.info(e.getMessage());
			tips.put(WebCode.SUCCESS, false);
			tips.put(WebCode.MSG, WebCode.FAILURE_DISABLE);
		}

		return tips;
	}

	/**
	 * 组件设计页面
	 * 
	 * @param code
	 * @return
	 */
	@ApiOperation("组件设计页面")
	@RequestMapping(value = "/design/{code}")
	public Map<String, Object> design(@PathVariable String code) {
		String page = "";
		Map<String, Object> tips = new HashMap<String, Object>();
		DashWidget dashWidget = dashWidgetService.get(code);
		tips.put("dashWidget", dashWidget);

		if (DashWidgetType.CHART.getValue().equals(dashWidget.getType())) {
			page = "/dashWidgetDesignChart";

			/* 获取图表组件数据绑定程序 */
			List<DashWidgetProvider> dashWidgetProviders = dashWidgetProviderService
					.select(new Filter.Builder().eq("widgetCode", code).build());
			if (CollectionUtils.isNotEmpty(dashWidgetProviders)) {
				tips.put("dashWidgetProvider", dashWidgetProviders.get(0));
			}
		} else if (DashWidgetType.DATA.getValue().equals(dashWidget.getType())) {
			page = "/dashWidgetDesignData";
		}
		tips.put("page", page);
		return tips;
	}

	/**
	 * 初始化数据提供器
	 * 
	 * @param code
	 *            组件编码
	 * @return
	 */
	@ApiOperation("初始化数据提供器")
	@SuppressWarnings("rawtypes")
	@PostMapping(value = "/initProvider/{code}")
	public Map<String, Object> initProvider(Page page, @PathVariable String code) {
		Map<String, Object> tips = new HashMap<String, Object>();

		try {
			/* 获取图表组件数据绑定程序 */
			List<DashWidgetProvider> dashWidgetProviders = dashWidgetProviderService
					.select(new Filter.Builder().eq("widgetCode", code).build());
			if (CollectionUtils.isNotEmpty(dashWidgetProviders)) {
				/* 获取组件配置 */
				DashWidgetConfig dashWidgetConfig = dashWidgetConfigService.get(code);
				tips.put("widgetConfig", dashWidgetConfig.getConfig());
				tips.put("version", dashWidgetConfig.getVersion());

				/* 获取当前用户在该组件上的权限 */
				// UserProfile user = UserProfileUtils.getUserProfile();
				PermitType permitType = dashWidgetDakService
						.queryMaxDashWidgetDak(Context.getIdentityContext().getIdentity().getId(), code);

				/* 初始化provider */
				DashWidgetProvider dashWidgetProvider = dashWidgetProviders.get(0);
				String id = dashWidgetProvider.getProviderCode();
				String params = dashWidgetProvider.getProviderParams();

				try {
					DataProviderFactory dataProviderFactory = factoryBean.getObject();
					DataProvider provider = dataProviderFactory.createDataProvider(id, page, params, permitType);
					tips.put("columns", provider.getDescriptor().getColumns());
					tips.put("sql", provider.getSql());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			tips.put(WebCode.SUCCESS, true);
		} catch (ServiceException e) {
			logger.info(e.getMessage());
			tips.put(WebCode.SUCCESS, false);
			tips.put(WebCode.MSG, e.getMessage());
		}

		return tips;
	}

	@ApiOperation("初始化图表")
	@PostMapping(value = "/initChartOptions")
	public Map<String, Object> initChartOptions(@RequestBody JSONObject jsonObject) {
		Map<String, Object> tips = new HashMap<String, Object>();
		try {

			/* 获取图表组件数据绑定程序 */
			List<DashWidgetProvider> dashWidgetProviders = dashWidgetProviderService
					.select(new Filter.Builder().eq("widgetCode", jsonObject.getString("widgetCode")).build());

			if (dashWidgetProviders.size() > 0) {
				/* 初始化provider */
				DashWidgetProvider dashWidgetProvider = dashWidgetProviders.get(0);
				DataProviderFactory dataProviderFactory = factoryBean.getObject();
				DataProvider provider = dataProviderFactory.createDataProvider(dashWidgetProvider.getProviderCode(),
						dashWidgetProvider.getProviderParams());

				// 图表渲染
				ChartRenderer renderer = ChartRendererFactory.createChartRenderer(jsonObject.getString("chartType"));
				String chartOptions = renderer.render(provider, jsonObject.getString("config"));
				tips.put("chartOptions", chartOptions);
				tips.put(WebCode.SUCCESS, true);
			}

		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage(), e);
			tips.put(WebCode.SUCCESS, false);
		}
		return tips;
	}

	/**
	 * 数据提供程序表分页查询
	 * 
	 * @param page
	 * @return
	 */
	@ApiOperation("数据提供程序表分页查询")
	@SuppressWarnings("rawtypes")
	@PostMapping(value = "/getDataByPage")
	public Map<String, Object> getDataByPage(Page page, @RequestBody JSONObject jsonObject) {

		Map<String, Object> result = new HashMap<String, Object>();
		List<Map<String, Object>> list = dataProviderService.query(jsonObject.getString("sql"), page);
		result.put(RESULT_TOTAL, page.getTotal());
		result.put(RESULT_ROWS, list);

		return result;
	}

}